/**
 * 
 * Opened Touchable RIA Framework - A Web RIA Javascript Framework
 * 
 * Copyright (c) 2012
 * Dual licensed under the MIT or GPL v2 licenses.
 * 
 * @author  CuTe_CuBe
 * @version $Id: vml.js 5 2012-03-09 10:44:54Z CC.HGFeng@gmail.com $
 */


(function(){

var a = OTR.Graph.Canvas;
    

/**
 * OTR.Graph.Canvas.Rect
 * 实现canvas矩形绘画功能 
 * 
 * @class OTR.Graph.Canvas.Rect
 * @constructor
 */
a.Rect = OTR.extend(OTR.Graph.Brush, {
    /**
     * canvas 绘制矩形实现方法
     * 
     * @return void
     */
    draw: function(){
        var ct = this._adapter.getContext(),
            s  = this._shape;
        
        var br = s.attr('borderRadius');

        ct.save();
        
        ct.fillStyle   = s.attr('background');
        ct.strokeStyle = s.attr('borderColor');
        ct.lineWidth   = s.attr('borderWidth');

        var x = s.attr('x') - 0.5,
            y = s.attr('y') - 0.5,
            w = s.attr('width'),
            h = s.attr('height');
        
        ct.beginPath();
        
        var r = x + w,
            b = y + h;

        ct.moveTo(x + br, y);
        ct.lineTo(r - br, y);
        ct.arc(r - br, y + br, br, 3*Math.PI/2,2*Math.PI, false);
        ct.lineTo(r, b - br);
        ct.arc(r - br, b - br, br, 0, Math.PI/2, false);
        ct.lineTo(x + br, b);
        ct.arc(x + br, b - br, br, Math.PI/2, Math.PI, false);
        //ct.lineTo(x, x + br);
        ct.arc(x + br, y + br, br , Math.PI, 3*Math.PI/2, false);
        ct.stroke();
        ct.fill();

        ct.closePath();
        ct.restore();
    }
});

/**
 * 圆形|椭圆绘画实现
 * 
 * @class OTR.Graph.Canvas.Cycle
 * @construct
 */
a.Cycle = OTR.extend(OTR.Graph.Brush, {
    
    /**
     * 
     * @return void
     */
    draw: function() {
        var s  = this._shape,
            ct = this._adapter.getContext(),
            w  = s.attr('width'),
            h  = s.attr('height'),
            d  = Math.max(w, h), 
            x  = s.attr('x'),
            y  = s.attr('y');
        
        ct.save();
        
        ct.fillStyle   = s.attr('background');
        ct.strokeStyle = s.attr('borderColor');
        ct.lineWidth   = s.attr('borderWidth');

        ct.beginPath();
        
        var scale = [1, 1];
        if (w != h) {
            scale = w > h
                  ? [1, h / d]
                  : [w / d, 1];
        }
        
        ct.scale(scale[0], scale[1]);
        ct.arc((x + w/2) / scale[0], (y + h/2) / scale[1], d/2, 0, Math.PI * 2);
        
        ct.fill();
        ct.stroke();
        
        ct.closePath();
        
        ct.restore();
    }
    
});

/**
 * 线段绘画实现
 * 
 * @class OTR.Graph.Canvas.Line
 * @construct
 */
a.Line = OTR.extend(OTR.Graph.Brush, {
    /**
     * 绘画实现方法
     * 
     * @return void
     */
    draw: function() {
        var s  = this._shape,
            ct = this._adapter.getContext(),
            fx = s.attr('x') - 0.5,
            fy = s.attr('y') - 0.5,
            dx = s.attr('dx') - 0.5,
            dy = s.attr('dy') - 0.5,
            sa = s.attr('startArrow'),
            ea = s.attr('endArrow');
        
        ct.save();
        
        ct.strokeStyle = s.attr('borderColor');
        ct.lineWidth   = s.attr('borderWidth');

        ct.beginPath();
        
        ct.moveTo(fx, fy);
        ct.lineTo(dx, dy);
        
        ct.stroke();
        
        ct.closePath();
        ct.restore();
        
        if (sa) {
            this._drawArrow(true, sa);
        }
        
        if (ea) {
            this._drawArrow(false, ea);
        }
    },
    
    /**
     * 绘画箭头
     * 
     * @param int start   是否开始
     * @param int rotate  角度
     * @return void
     */
    _drawArrow: function(start, type) {
        var s  = this._shape, a,
            pos = this._getArrowPos(start),
            rotate = this._getArrowRotate(start);

        switch (type) {
            case 'Cycle':
                a  = new OTR.Graph.Cycle({
                    borderColor: s.attr('borderColor'),
                    background:  s.attr('borderColor'),
                    width: 8,
                    height: 8,
                    x: pos.x - 4,
                    y: pos.y - 4
                });
            break;
            case 'Block':
            default:
                a  = new OTR.Graph.Polygon({
                    borderColor: s.attr('borderColor'),
                    background:  s.attr('borderColor'),
                    sideCount: 3,
                    width: 8,
                    height: 8,
                    x: pos.x - 4,
                    y: pos.y - 4,
                    rotate: rotate
                });
                break;
        }
        
        this._adapter.drawShape(a);
    },
    
    /**
     * 获取箭头位置
     * 
     * @protected
     * @param start
     * @return object
     */
    _getArrowPos: function(start) {
        var s = this._shape;
        
        if (start) {
            return {x: s.attr('x'), y: s.attr('y')};
        }
        
        return {x: s.attr('dx'), y: s.attr('dy')};
    },
    
    /**
     * 获取箭头位置
     * 
     * @protected
     * @param start
     * @return object
     */
    _getArrowRotate: function(start) {
        var s = this._shape,
            x = s.attr('x'),
            y = s.attr('y'),
            dx = s.attr('dx'),
            dy = s.attr('dy'), r;
        
        if (dy - y == 0) {
            r = dx > x ? 90 : 270;
        } else {
            r = Math.atan((dx-x)/(dy-y)) / Math.PI * 180;
            
            if (dx - x < 0) {
                r = r - 180;
            }
        }
        
        return r;
    }
});

/**
 * 线段绘画实现
 * 
 * @class OTR.Graph.Canvas.Line
 * @construct
 */
a.PolyLine = OTR.extend(a.Line, {
    /**
     * 绘画实现方法
     * 
     * @return void
     */
    draw: function() {
        var s  = this._shape,
            ct = this._adapter.getContext(),
            points = s.attr('points');

        if(!points || points.length < 2) {
            return ;
        }
        
        ct.save();
        
        ct.strokeStyle = s.attr('borderColor');
        ct.lineWidth   = s.attr('borderWidth');

        ct.beginPath();
        
        var i = 0, k = points.length;
        for ( ; i < k; i++) {
            if (i == 0) {
                ct.moveTo(points[i].x - 0.5, points[i].y - 0.5);
                continue ;
            }
            ct.lineTo(points[i].x - 0.5, points[i].y - 0.5);
        }
        
        ct.stroke();
        
        ct.closePath();
        ct.restore();
        
        if (s.attr('startArrow')) {
            this._drawArrow(true, s.attr('startArrow'));
        }
        
        if (s.attr('endArrow')) {
            this._drawArrow(false, s.attr('endArrow'));
        }
    },
    
    /**
     * 获取箭头位置
     * 
     * @protected
     * @param start
     * @return object
     */
    _getArrowPos: function(start) {
        var s = this._shape,
            points = s.attr('points'),
            l = points.length;
        
        if (start) {
            return {x: points[0].x, y: points[0].y};
        }
        
        return {x: points[l-1].x, y: points[l-1].y};
    },
    
    /**
     * 获取箭头位置
     * 
     * @param start
     * @return object
     */
    _getArrowRotate: function(start) {
        var s = this._shape,
            points = s.attr('points'),
            pc = points.length,
            x = start ? points[0].x : points[pc - 2].x,
            y = start ? points[0].y : points[pc - 2].y,
            dx = start ? points[1].x : points[pc - 1].x,
            dy = start ? points[1].y : points[pc - 1].y,
            r;

        if (dy - y == 0) {
            r =  dx > x ? 90 : 270;
        } else {
            r = Math.atan((dx-x)/(dy-y)) / Math.PI * 180;
            
            if (dx - x < 0) {
                r = r - 180;
            }
        }
        
        return r;
    }
});

/**
 * 线段绘画实现
 * 
 * @class OTR.Graph.Canvas.Polygon
 * @construct
 */
a.Polygon = OTR.extend(OTR.Graph.Brush, {
    /**
     * 绘画实现方法
     * 
     * @return void
     */
    draw: function() {
        var s  = this._shape,
            ct = this._adapter.getContext(),
            points = s.getPoints();

        if(!points || points.length < 2) {
            return ;
        }

        ct.save();
        
        ct.fillStyle   = s.attr('background');
        ct.strokeStyle = s.attr('borderColor');
        ct.lineWidth   = s.attr('borderWidth');

        ct.beginPath();
        
        var i = 0, k = points.length;
        for ( ; i < k; i++) {
            if (i == 0) {
                ct.moveTo(points[i].x - 0.5, points[i].y - 0.5);
                continue ;
            }
            ct.lineTo(points[i].x - 0.5, points[i].y - 0.5);
        }
        ct.lineTo(points[0].x - 0.5, points[0].y - 0.5);
        
        ct.stroke();
        ct.fill();
        
        ct.closePath();
        
        ct.restore();
    }
});

/**
 * 文字绘画实现
 * 
 * @class OTR.Graph.Canvas.Text
 * @construct
 */
a.Text = OTR.extend(OTR.Graph.Brush, {
    /**
     * 绘画实现方法
     * 
     * @return void
     */
    draw: function() {
        var s  = this._shape,
            ct = this._adapter.getContext(),
            text = s.attr('text'),
            lw   = s.attr('lineWidth');
        
        ct.save();
        
        ct.strokeStyle = s.attr('borderColor');
        ct.lineWidth   = lw;
        ct.font        = s.attr('fontSize') + ' ' + s.attr('fontFamily');
        ct.fllColor    = s.attr('color');
        ct.textBaseline= s.attr('baseLine');

        ct.beginPath();
        
        var x  = s.attr('x'),
            y  = s.attr('y'),
            mw = s.attr('maxWidth');
        
        if (!mw) {
            ct.fillText(text, x, y);
            if (lw > 0) {
                ct.strokeText(text, x, y);
            }
        } else {
            ct.fillText(text, x, y, mw);
            if (lw > 0) {
                ct.strokeText(text, x, y, mw);
            }
        }
        
        ct.closePath();
        ct.restore();
    }
});

})();